<!--
 * @Author: wangshuixin 2412658453@qq.com
 * @Date: 2024-11-05 15:31:57
 * @LastEditors: wangshuixin 2412658453@qq.com
 * @LastEditTime: 2024-12-24 15:00:22
 * @FilePath: \sr_system_manager_ui\src\components\TableForm\index.vue
 * @Description: 表格组件
-->

<script setup lang="ts">
import type { TableColumnItem } from '@/types/component'
import ToolBar from "./ToolBar.vue"

const props = defineProps({
   data: { // 数据
      type: Array,
      required: true,
      default: () => [],
   },
   tableLoading: { // 加载loading
      type: Boolean,
      default: false,
   },
   columns: { // 表头设置
      type: Array as () => TableColumnItem[],
      default: []
   },
   showPagination: { // 显示分页选择器
      type: Boolean,
      default: true,
   },
   totalCount: { // 数据总条数
      type: Number,
      default: 0
   },
   showRowSelection: { // 显示行选择器
      type: Boolean,
      default: false
   },
   rowSelectionWidth: { // 行选择器的宽度
      type: Number,
      default: 30
   },
   rowSelectionFixed: { // 行选择器是否固定
      type: Boolean,
      default: false
   },
   rowSelectionAlign: { // 行选择器的位置
      type: String,
      default: 'left'
   },
   paginationLayout: {
      type: String,
      default: 'total, sizes, prev, pager, next, jumper'
   },
   pageSize: {
      type: Number,
      default: 20
   },
   download: { // 下载回调函数
      type: Function,
   },
   pageSizes: { // 页码可选参数
      type: Array,
      default() {
         return [10, 20, 30, 50]
      }
   },
   /* 展示表格toolBar工具栏 */
   showToolBar: {
      type: Boolean,
      default: false,
   },
   btnTitle: {
      type: String,
      default: '按钮'
   },
   /* 隐藏toolBar左边菜单 */
   hideLeftMenu: {
      type: Boolean,
      default: true,
   },
   /* 是否显示检索条件 */
   showSearch: {
      type: Boolean,
      default: true,
   },
   /* 是否显示检索图标 */
   showSearchIcon: {
      type: Boolean,
      default: true,
   },
   /* 显隐列类型（transfer穿梭框、checkbox复选框） */
   showColumnsType: {
      type: String,
      default: "checkbox",
   },
   /* 是否显示边框 */
   border: {
      type: Boolean,
      default: true,
   },
   /* 工具栏高度 */
   toolBarHeight: {
      type: String,
      default: '64px'
   },
   autoHeight: {
      type: Boolean,
      default: true
   },
   /* toolbar第一个按钮显隐 */
   hideRightFirstBtn: {
      type: Boolean,
      default: false,
   },
   /* toolbar第二个按钮显隐 */
   hideRightSecondBtn: {
      type: Boolean,
      default: false,
   },
   /* toolbar第三个按钮显隐 */
   hideRightThirdBtn: {
      type: Boolean,
      default: true,
   },
   /* toolbar第四个按钮显隐 */
   hideRightForthBtn: {
      type: Boolean,
      default: false,
   },
   /* 第一个按钮权限 */
   rightFirstBtnPermission: {
      type: Array as () => String[],
      default: () => ['*:*:*']
   },
   /* 左侧菜单按钮权限 */
   leftMenuPermission: {
      type: Array as () => String[],
      default: () => ['*:*:*']
   }
})

const emits = defineEmits(['update:showSearch', 'refresh', 'selectRows', 'rowDblclick', 'btnClick'])

// 当前分页
const currentPage = ref(1)
// 分页尺寸
const currentPageSize = ref(props.pageSize)
// 选中的每行数据的id
const ids = ref([])
// 显隐列数据
const columnsList = ref<TableColumnItem[]>([])
// 整个表格区域的引用
const tableContainerRef = ref()
// 表格头部的工具栏引用
const toolBarRef = ref()
// 表格最大高度
const maxHeight = ref('600px')
// 是否显示检索条件
const showSearch = ref(props.showSearch)

// 行选择器选中的数据
const rowSelectionChange = (rowDataList: any) => {
   ids.value = rowDataList.map(rowData => rowData.id);
   emits('selectRows', ids.value)
}

// 双击数据行
const onRowDblClick = (record: any) => {
   emits('rowDblclick', record)
}

// 刷新表格数据
const refreshTableData = (reqParams: { page: number, limit: number }) => {
   const params = {
      page: reqParams.page,
      size: reqParams.limit,
   }
   currentPageSize.value = reqParams.limit
   emits('refresh', params)
}

// 回到第一页进行刷新
const refreshInitPage = () => {
   const params = {
      page: 1,
      size: currentPageSize.value,
   }
   // 重置页面
   currentPage.value = 1
   emits('refresh', params)
}

// 下载
const download = () => {
   if (props.download) {
      if (ids.value.length > 0) {
         props.download(ids.value)
      } else {
         props.download([])
      }
   } else {
      console.log("默认下载")
   }
}
// 搜索
function toggleSearch() {
   showSearch.value = !showSearch.value
   emits("update:showSearch", !props.showSearch)
}

watch(
   () => props.columns,
   () => {
      if (props.columns) {
         // 显隐列初始默认隐藏列
         columnsList.value = props.columns.map((column: TableColumnItem) => {
            return {
               ...column,
               label: column.title,
               key: column.dataIndex,
               visible: true,
               //  disabled: true
            }
         })
      }
   }, {
   immediate: true
}
)

onMounted(() => {
   if (tableContainerRef.value && !props.autoHeight) {
      maxHeight.value = `${tableContainerRef.value.offsetHeight - 60 - (toolBarRef.value ? toolBarRef.value.offsetHeight : 50)}px`
   }
})

defineExpose({
   refreshInitPage,
   selectedRowKeys: ids || []
})
</script>


<template>
   <div ref="tableContainerRef" class="table-container">
      <div ref="toolBarRef" class="tool-bar">
         <slot name="toolBar">
            <ToolBar v-if="props.showToolBar" :showSearch="showSearch" :btnTitle="props.btnTitle"
               :showSearchIcon="props.showSearchIcon" :columns="columnsList" :showColumnsType="props.showColumnsType"
               :hideLeftMenu="props.hideLeftMenu" :height="props.toolBarHeight"
               :hide-right-first-btn="props.hideRightFirstBtn" :hide-right-second-btn="props.hideRightSecondBtn"
               :hide-right-third-btn="props.hideRightThirdBtn" :hide-right-forth-btn="props.hideRightForthBtn"
               :right-first-btn-permission="props.rightFirstBtnPermission"
               :left-menu-permission="props.leftMenuPermission"
               @btn-click="$emit('btnClick')" @download="download" @refresh="refreshInitPage" @search="toggleSearch">
               <template #leftMenu>
                  <slot name="leftMenu"></slot>
               </template>
            </ToolBar>
         </slot>
      </div>
      <div class="table-wrapper">
         <el-table v-loading="props.tableLoading" :data="props.data" :max-height="props.autoHeight ? undefined : maxHeight" :border="props.border" stripe v-bind="$attrs" @selection-change="rowSelectionChange" @row-dblclick="onRowDblClick">
            <el-table-column v-if="props.showRowSelection" type="selection" :align="props.rowSelectionAlign" :width="props.rowSelectionWidth" :fixed="props.rowSelectionFixed" />
            <el-table-column v-for="columnItem in columnsList.filter(column => column.visible)" :key="columnItem.title"
               :label="columnItem.title" :show-overflow-tooltip="columnItem.tooltip" :prop="columnItem.dataIndex"
               v-bind="columnItem" align="left">
               <template #header>
                  <div style="display: flex;flex-direction: row;">
                     <div v-if="columnItem.required" style="color: #F53F3F;margin-right: 4px;">*</div>
                     {{ columnItem.title }}
                  </div>
               </template>
               <template v-if="columnItem.slotName" #default="scope">
                  <!-- 在这里，scope.row 包含当前行的数据 -->
                  <slot :name="columnItem.slotName" :record="scope.row" :column="columnItem" :rowIndex="scope.$index">
                     <span>{{ scope.row[columnItem.dataIndex] }}</span>
                  </slot>
               </template>
            </el-table-column>
         </el-table>
      </div>
      <div v-show="props.showPagination && props.totalCount > 0" class="pagination">
         <pagination :total="props.totalCount" :layout="props.paginationLayout" v-model:page="currentPage"
            v-model:limit="currentPageSize" @pagination="refreshTableData" :pageSizes="props.pageSizes" />
      </div>
   </div>
</template>

<style scoped lang="scss">
.table-container {
   display: flex;
   flex-direction: column;
   height: 100%;
}

.tool-bar {
   // flex: none;
   // position: sticky;
   // top: 0; /* 固定在顶部 */
   // z-index: 11; /* 确保分页在表格上方 */
   background-color: white;
}

.table-wrapper {
   // flex: 1;
   /* 填充剩余空间 */
   overflow: hidden;
   overflow-y: auto;
   /* 允许垂直滚动 */
   background-color: white;
   width: 100%;
   :deep(.el-button) {
      @apply ml-0 px-[6px]
   }
}

.pagination {
   //   flex: none; /* 固定高度 */
   //   position: sticky;
   //   bottom: 0; /* 固定在底部 */
   background-color: white;
   /* 确保分页背景不透明 */
   align-items: center;
   //   z-index: 11; /* 确保分页在表格上方 */
   margin-top: 0px;
}

:deep(.pagination-container) {
   margin: 0;
   padding: 0px 0px !important;
   margin-top: 20px;
}

/* 设置表格边框 */
// :deep(.el-table__inner-wrapper) {
//    border: 1px solid #E5E6EB;
// }
/* 表头高度 */
// :deep(.el-table .el-table__header-wrapper th, .el-table .el-table__fixed-header-wrapper th) {
//    height: 50px !important;
// }
/* 表格row */
// :deep(.el-table .cell) {
//    height: 50px;
//    line-height: 50px;
//    padding: 0px;
//    padding-left: 16px;
//    padding-right: 16px;
//    border-right: 1px solid #E5E6EB;
// }
</style>